package controller

import (
	"ginweb/internal/domain/order"
	"ginweb/internal/service/command"
	"ginweb/internal/service/query"
	"ginweb/pkg/validator"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
)

type OrderController struct {
	orderService *command.OrderService
	queryService *query.OrderService
}

func NewOrderController(orderService *command.OrderService, queryService *query.OrderService) *OrderController {
	return &OrderController{orderService: orderService, queryService: queryService}
}

func (c *OrderController) CreateOrder(ctx *gin.Context) {
	var order order.Order
	if err := validator.BindAndValidate(ctx, &order); err != nil {
		logrus.WithError(err).Error("Failed to bind and validate order data")
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := c.orderService.CreateOrder(&order); err != nil {
		logrus.WithError(err).Error("Failed to create order")
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	logrus.WithField("order", order).Info("Order created")
	ctx.JSON(http.StatusCreated, gin.H{"message": "Order created", "order": order})
}

func (c *OrderController) GetOrder(ctx *gin.Context) {
	id := ctx.Param("id")
	order, err := c.queryService.GetOrder(id)
	if err != nil {
		logrus.WithError(err).Error("Failed to get order")
		ctx.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
		return
	}

	logrus.WithField("order", order).Info("Order retrieved")
	ctx.JSON(http.StatusOK, gin.H{"order": order})
}

func (c *OrderController) UpdateOrder(ctx *gin.Context) {
	var order order.Order
	if err := validator.BindAndValidate(ctx, &order); err != nil {
		logrus.WithError(err).Error("Failed to bind and validate order data")
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := c.orderService.UpdateOrder(&order); err != nil {
		logrus.WithError(err).Error("Failed to update order")
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	logrus.WithField("order", order).Info("Order updated")
	ctx.JSON(http.StatusOK, gin.H{"message": "Order updated", "order": order})
}

func (c *OrderController) DeleteOrder(ctx *gin.Context) {
	id := ctx.Param("id")
	if err := c.orderService.DeleteOrder(id); err != nil {
		logrus.WithError(err).Error("Failed to delete order")
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	logrus.WithField("order_id", id).Info("Order deleted")
	ctx.JSON(http.StatusOK, gin.H{"message": "Order deleted"})
}
